home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SoundMaker 2003 (Professional Edition)
/
SoundMaker 2003 - Professional Edition.iso
/
midi tool
/
midioxse.exe
/
DATA.1
/
midiecho.rex
< prev
next >
Wrap
OS/2 REXX Batch file
|
1999-03-27
|
4KB
|
147 lines
/* REXX: Simple MIDI Echo loop */
/* Parameters: Delay Repeats Decay */
/* Example: 250 10 3 */
/* Designed to be used without diverting of input */
call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
call SysLoadFuncs
qName = MoxGetQueueName()
oldq = RxQueue( 'Set', qName )
/* MIDI-OX creates a semaphore with same name as queue */
sem = SysOpenEventSem( qName )
running = (sem <> 0)
/* Get Command line (if any). */
parse arg dly rpt dcy
delay = 250 /* 250 millisecs */
if dly <> '' then
delay = dly
repeats = 8 /* 8 repeats */
if rpt <> '' then
repeats = rpt
decay = 1 /* decay rate of 1 (0 = none, 10 = complete decay) */
if dcy <> '' then
decay = dcy
say "Echo Delay (msecs):" delay
say "Echo Repeats:" repeats
say "Decay Rate:" decay
/* Use an Object REXX Queue to store note ons and offs */
echoQ = .queue~new
say "Initialized..."
do while running
someInput = (Queued() <> 0)
someEcho = (echoQ~Items() <> 0)
do while someInput | someEcho
now = MoxGetSystemTime()
if someInput
then do
pull timestamp status data1 data2
/* Sent by MIDI-OX to signify end of program */
if timestamp = 'END_DATA'
then do
running = 0
leave
end
if status = 144
then do /* only notes */
later = now + delay
event = .EchoEvent~New( later, delay, repeats, decay, status, data1, data2 )
echoQ~Queue( event )
end
end
if someEcho
then do
/* see if the queue head has expired yet */
event = echoQ~Peek()
if event~HasExpired( now )
then do
/* actually remove from Queue */
event = echoQ~Pull()
ret = MoxOutputMidi( event~status, event~note, event~velocity )
if ret <> 0
then do
msg = "Error code: " || ret
call RxMessageBox msg, '', 'OK', 'STOP'
end
/* do we have more echos to do? */
if event~Cycle() then
echoQ~Queue( event )
end
end
someInput = (Queued() <> 0)
someEcho = (echoQ~Items() <> 0)
end
if running
then do
/* queue is empty: you could do other processing here */
ret = SysWaitEventSem( sem )
if ret <> 0
then do
running = .false
call RxMessageBox "Sem Code:" || ret, "err", 'OK', 'STOP'
end
end
end
call SysDropFuncs
exit
/* ========================================================== */
::class EchoEvent subclass Object
::method Init
expose expire delay echos decay status note velocity
use arg expire, delay, echos, decay, status, note, velocity
/* initial velocity should be less */
velocity = velocity * 3 % 4
return
::method expire attribute
::method echos attribute
::method status attribute
::method note attribute
::method velocity attribute
::method HasExpired
expose expire
use arg now
if now > expire then
return 1
return 0
::method Cycle
expose echos velocity expire delay decay
echos = echos - 1 /* one less echoes to go */
if echos > 0
then do
/* softer than last echo */
velocity = velocity * (10 - decay) % 10
expire = expire + delay
return 1
end
return 0